import {type ForumStatus, parseForumStatus} from "./ForumStatus.ts";
import {type Attachment, buildAttachment} from "./Reply.ts";
import {decode} from "../utils/StrUtils.ts";
import {TopicStatus} from "./TopicStatus.ts";
import {canEncodeWithGB18030} from "../utils/encoding.ts";
import {format} from "date-fns";

export interface PrepareBody {
    auth: string
    content: string
    fid: number
    tid: number | undefined
    pid: number | undefined
    forum: {
        fid: number
        name: string
        status: ForumStatus[] | undefined
    }
    colTopic: {
        tid: number
        title: string
    } | undefined

    warning: string[] | undefined
    costInfo: string | undefined

    /*以下字段仅出现在 编辑操作时*/

    hidden: 0 | 1 | 2 | undefined
    attachments: Attachment[] | undefined
    modifyAppend: boolean | undefined
    title: string | undefined
    contentOriginal: string | undefined
}

export const buildPrepareBody = (data: any): PrepareBody => {
    return {
        auth: data.auth,
        content: decode(data.content) || "",
        fid: data.fid,
        tid: data.tid,
        pid: data.pid,
        costInfo: data.cost_info,
        forum: {
            fid: data.__F.fid,
            name: data.__F.name,
            status: parseForumStatus(data.__F.bit_data),
        },
        colTopic: data.__ST ? {
            title: decode(data.__ST.subject) || "",
            tid: data.__ST.tid,
        } : undefined,
        warning: data.warning ? Object.values(data.warning).map((i: any) => i[1]) : undefined,
        hidden: data.if_hidden === '1' ? 1 : 2,
        attachments: data.attachs ? Object.keys(data.attachs)?.map(k => buildAttachment(data.attachs[k])) : undefined,
        modifyAppend: data.modify_append,
        title: decode(data.subject),
        contentOriginal: decode(data.content_org),
    }
}

export interface UploadBody {
    attachments: string
    attachments_check: string
    isImg: boolean
    thumb: number
    url: string

    blob: string
    thumbs: string[]
    file: File

    // 错误信息
    error_txt?: string | undefined
    error_code?: number | undefined
    error?: string | undefined
}

export interface UploadError {
    file: File
    message?: string | undefined
    code?: number | undefined
    error?: string | undefined
}


export interface PostParam {
    title?: string | undefined
    content: string | undefined
    modifyAppend?: boolean | undefined
    hidden?: 0 | 1 | 2 | undefined
    anony?: boolean | undefined
    replyOnce?: boolean | undefined
    attachments?: UploadBody[] | undefined
    mention?: boolean | undefined
}

export const postParamToFormData = (data: PostParam): FormData => {
    const formData = new FormData();
    const {title, modifyAppend, anony, replyOnce, hidden, mention, attachments} = data

    // 检查unicode编码
    let tempContent = []
    for (const symbol of (data.content || "")) {
        const codePoint = `&#${symbol.codePointAt(0)};`
        const canEncode = canEncodeWithGB18030(symbol);
        // console.log(symbol, codePoint, canEncode)
        tempContent.push(canEncode ? symbol : codePoint)
    }
    const content = tempContent.join('')


    if (title) formData.append("post_subject", title);
    // 自动字数补丁
    formData.append("post_content", content.length > 6 ? content : (content + '[b][/b]'));
    if (modifyAppend) formData.append("modify_append", '1');
    if (hidden !== undefined) formData.append("hidden", hidden === 1 ? '1' : '2');
    if (anony) formData.append("anony", '1');
    if (replyOnce) formData.append("tpic_misc_bit1", Math.pow(2, TopicStatus.REPLY_ONCE).toString());

    if (mention && content) {
        const regExp = /\[@(.+?)]/g
        const arr = []
        let match
        while (match = regExp.exec(content)) {
            arr.push(match[1])
        }
        if (arr.length > 0) {
            formData.append("mention", arr.join("\t"))
        }
    }
    if (attachments) {
        formData.append("attachments", attachments.map(i => i.attachments).join("\t"))
        formData.append("attachments_check", attachments.map(i => i.attachments_check).join("\t"))
    }

    return formData
}

export const uploadParamToFormData = (auth: string, fid: number, file: File, description?: string | undefined): FormData => {
    const autoSize = file.size > 4 * 1024 * 1024 ? "1" : "0"
    // 本地日期 yyyy-MM-dd HH:mm:ss
    const date = format(new Date(), 'yy-MM-dd HH:mm:ss')

    const prefix = "attachment_file0"
    const formData = new FormData();
    formData.append("auth", auth)
    formData.append("fid", fid.toString())
    formData.append("v2", "1")
    formData.append("func", "upload")
    formData.append("__inchst", "UTF8")
    formData.append("__output", "11")
    formData.append("origin_domain", "bbs.nga.cn")
    formData.append(prefix + "_img", "0")
    formData.append(prefix + "_auto_size", autoSize)
    formData.append(prefix + "_dscp", description || `upload at ${date}`)
    formData.append(prefix + "_url_utf8_name", encodeURI(file.name))
    formData.append(prefix, file, file.name)
    return formData
}